﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GenerateNewProject
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            var appsetting = System.Configuration.ConfigurationManager.AppSettings;

            tbOldProjectName.Text = appsetting["OldProjectName"].ToString();
            tbReplaceExtend.Text = appsetting["ReplaceExtendFile"].ToString();
            tbExcludeFile.Text= appsetting["ExincludeFiles"].ToString();
            tbExcludeFloder.Text = appsetting["ExincludeFloders"].ToString();

            CopyExincludeFloders= appsetting["CopyExincludeFloders"].ToString().Split(',',StringSplitOptions.RemoveEmptyEntries).ToList();

            cbReplaceFileName.Checked = Convert.ToBoolean(appsetting["IsReplaceFileName"].ToString());
            cbReplaceFileContent.Checked = Convert.ToBoolean(appsetting["IsReplaceFileContent"].ToString());
            cbReplaceFloderName.Checked = Convert.ToBoolean(appsetting["IsReplaceFloderName"].ToString());

           
        }

       
       

        //旧项目名称
        public string OldProjectName { get; set; }
        /// <summary>
        /// 新项目名称
        /// </summary>
        public string NewProjectName { get; set; }

        /// <summary>
        /// 替换排除文件
        /// </summary>
        Dictionary<string, string> ExincludeFiles = new Dictionary<string, string>();
        /// <summary>
        /// 替换排除文件夹
        /// </summary>
        Dictionary<string, string> ExincludeFloders = new Dictionary<string, string>();
        /// <summary>
        /// 替换的扩展文件后缀
        /// </summary>
        Dictionary<string, string> ReplaceExtendFile = new Dictionary<string, string>();

        /// <summary>
        /// 复制排除文件夹
        /// </summary>
        public List<string> CopyExincludeFloders = new List<string>() {".git",".vs" };
        /// <summary>
        /// 是否替换文件名
        /// </summary>
        public bool IsReplaceFileName { get; set; }
        /// <summary>
        /// 是否替换文件内容
        /// </summary>
        public bool IsReplaceFileContent { get; set; }
        /// <summary>
        /// 是否替换文件内容
        /// </summary>
        public bool IsReplaceFloderName { get; set; }

        private void btnSelectSourceDir_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择文件路径";

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string foldPath = dialog.SelectedPath;
                DirectoryInfo theFolder = new DirectoryInfo(foldPath);
                tbSelectSourceFloderPath.Text = theFolder.FullName;
            }
        }

        private void btnSelectNewProjectFloder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.Description = "请选择文件路径";

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string foldPath = dialog.SelectedPath;
                DirectoryInfo theFolder = new DirectoryInfo(foldPath);
                tbNewProjectName.Text = theFolder.FullName;
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (tbSelectSourceFloderPath.Text == tbNewProjectName.Text)
            {
                MessageBox.Show("请不要选择相同文件夹保存！");
                return;
            }

            if (!Directory.Exists(tbSelectSourceFloderPath.Text))
            {
                MessageBox.Show("选择的源路径不存在，请检查！");
                return;
            }
            if (!Directory.Exists(tbNewProjectName.Text))
            {
                try
                {
                    var dirinfo = Directory.CreateDirectory(tbNewProjectName.Text);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, caption: "目标文件夹不存在，创建文件夹错误！");
                    return;
                }
            }
            if(string.IsNullOrWhiteSpace(tbOldProjectName.Text))
            {
                MessageBox.Show("源项目名称不能为空");
                return;
            }
            if (string.IsNullOrWhiteSpace(tbNewProjectName.Text))
            {
                MessageBox.Show("新项目名称不能为空");
                return;
            }
            if(tbOldProjectName.Text==tbNewProjectName.Text)
            {
                MessageBox.Show("新项目名称与源项目名称相同了！");
                return;
            }

            IsReplaceFileContent = cbReplaceFileContent.Checked;
            IsReplaceFileName = cbReplaceFileName.Checked;

            OldProjectName = tbOldProjectName.Text.Trim();
            NewProjectName = tbNewProjectName.Text.Trim();

            {
                ExincludeFiles.Clear();
                var temps = tbExcludeFile.Text.Split(new char[] { '\r', '\n', ',' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var item in temps)
                {
                    ExincludeFiles.Add(item, item);
                }
            }
            {
                ExincludeFloders.Clear();
                var temps = tbExcludeFloder.Text.Split(new char[] { '\r', '\n', ',' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in temps)
                {
                    ExincludeFloders.Add(item, item);
                }
            }
            {
                ReplaceExtendFile.Clear();
                //替换的扩展文件后缀
                var temps = tbReplaceExtend.Text.Split(new char[] { '\r', '\n',',' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in temps)
                {
                    ReplaceExtendFile.Add(item, item);
                }

            }

            try
            {
                lbMsg.Text = "开始复制源项目文件到新目录。。。";
                //  return;
                var copystate = CopyDirectory(tbSelectSourceFloderPath.Text, btNewProjectFloder.Text, true);
                lbMsg.Text = "复制源项目文件到新目录完成，开始替换源项目名称及源项目文件内容。。。";
                ReplaceName(btNewProjectFloder.Text);

                lbMsg.Text = "创建新项目完成";
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }

        }

        


      
        /// <summary>
        /// 替换文件名称或文件内容
        /// </summary>
        /// <param name="path">文件夹路径</param>
        private void ReplaceName(string path)
        {
            DirectoryInfo theFolder = new DirectoryInfo(path);
            DirectoryInfo[] dirInfo = theFolder.GetDirectories();
            foreach (DirectoryInfo NextFolder in dirInfo)
            {
                if (ExincludeFloders.Keys.Any(o => NextFolder.Name.Trim().ToLower() == o.ToLower()))
                {
                    //排除的文件夹，跳过
                }
                else
                {
                    //没有排除当前文件夹，可以继续遍历处理
                    ReplaceName(NextFolder.FullName);

                    //注意大小写
                    if (NextFolder.Name.Contains(OldProjectName))
                    {
                        //替换名称
                        System.IO.DirectoryInfo folder = new System.IO.DirectoryInfo(NextFolder.FullName);
                        folder.MoveTo(NextFolder.Parent.FullName + "\\" + Regex.Replace(NextFolder.Name, OldProjectName, NewProjectName));
                    }
                }
            }
            #region 文件名，文件内容替换
            // this.listBox1.Items.Add(NextFolder.Name);
            FileInfo[] fileInfo = theFolder.GetFiles();
            foreach (FileInfo NextFile in fileInfo)  //遍历文件
            {
                //判断是否排除的文件名
                if (ExincludeFiles.Keys.Any(o=>o.ToLower()==NextFile.Name.ToLower()))
                {
                    //排除的文件名，跳过
                    continue;
                }

                //判断是否排除的扩展名
                if(ReplaceExtendFile.Keys.All(o=>o.ToLower()!=NextFile.Extension.ToLower()))
                {
                    //不包含当前可替换扩展名，跳过
                    continue;
                }



                // this.listBox2.Items.Add(NextFile.Name);
                ReplaceFileContent(NextFile.FullName, OldProjectName, NewProjectName);
                //替换新名称
                if (NextFile.Name.Contains(OldProjectName))
                {
                    var a = Regex.Replace(NextFile.Name, OldProjectName, NewProjectName);
                    var b = NextFile.DirectoryName + "\\" + a;
                    File.Move(NextFile.FullName, b);
                }
            }
            #endregion
        }



        /// <summary>
        /// 修改文件夹名称
        /// </summary>
        /// <param name="path">文件夹路径</param>
        private void ModifyFloderName(string path)
        {
            DirectoryInfo theFolder = new DirectoryInfo(path);
            DirectoryInfo[] dirInfo = theFolder.GetDirectories();
            foreach (DirectoryInfo NextFolder in dirInfo)
            {
                //判断排除文件夹，排除的文件夹，不遍历，不操作
                bool isexincludefloder = false;
                foreach (var item in ExincludeFloders.Keys)
                {
                    if (NextFolder.Name.Trim().ToLower() == item.ToLower())
                    {
                        isexincludefloder = true;
                        break;
                    }
                }

                if (isexincludefloder == false)
                {
                    //没有排除当前文件夹，可以继续遍历处理
                    ModifyFloderName(NextFolder.FullName);

                    //注意大小写
                    if (NextFolder.Name.Contains(OldProjectName))
                    {
                        //替换名称
                        System.IO.DirectoryInfo folder = new System.IO.DirectoryInfo(NextFolder.FullName);
                        folder.MoveTo(NextFolder.Parent.FullName + "\\" + Regex.Replace(NextFolder.Name, OldProjectName, NewProjectName));
                    }
                }
            }
        }


        /// <summary>
        /// 替换文件内容
        /// </summary>
        /// <param name="strFilePath">txt等文件的路径</param>
        /// <param name="strIndex">索引的字符串，定位到某一行</param>
        /// <param name="newValue">替换新值</param>
        private static void ReplaceFileContent(string strFilePath, string oldValue, string newValue)
        {
            if (File.Exists(strFilePath))
            {
                string strContent = File.ReadAllText(strFilePath);
                strContent = Regex.Replace(strContent, oldValue, newValue);
                File.WriteAllText(strFilePath, strContent);
            }
        }

        /// <summary>
        /// 复制整个文件夹
        /// </summary>
        /// <param name="SourcePath">原文件夹路径</param>
        /// <param name="DestinationPath">目标文件夹路径</param>
        /// <param name="overwriteexisting">是否覆盖已存在文件</param>
        /// <returns></returns>
        private  bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)
        {
            bool ret = false;
            try
            {
                SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\";
                DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\";

                if (Directory.Exists(SourcePath))
                {
                    if (Directory.Exists(DestinationPath) == false)
                        Directory.CreateDirectory(DestinationPath);

                    foreach (string fls in Directory.GetFiles(SourcePath))
                    {
                        FileInfo flinfo = new FileInfo(fls);
                        flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
                    }
                    foreach (string drs in Directory.GetDirectories(SourcePath))
                    {
                        DirectoryInfo drinfo = new DirectoryInfo(drs);
                        //CopyExincludeFloders
                        //复制排除目录
                        if (CopyExincludeFloders.Any(o => o.ToLower() == drinfo.Name.ToLower())) continue;
                        if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false)
                            ret = false;
                    }
                }
                ret = true;
            }
            catch (Exception ex)
            {
                ret = false;
            }
            return ret;
        }




        public delegate void CopyFileCountDelegate();//声明一个更新主线程的委托

        //更新UI
        private void CopyFileCount()
        {
            if (InvokeRequired)
            {
                this.Invoke(new CopyFileCountDelegate(delegate 
                {
                  
                }));
            }
            else
            {
               
            }
        }
    }
}
